home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / graphics.17 / graphics / graphics-0.17 / plot2tek / arc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-03-12  |  3.3 KB  |  137 lines

  1. /* libtek, a library of functions for tektronics 4010 compatible devices.
  2.    Copyright (C) 1989 Free Software Foundation, Inc.
  3.  
  4. libtek is distributed in the hope that it will be useful, but WITHOUT ANY
  5. WARRANTY.  No author or distributor accepts responsibility to anyone for the
  6. consequences of using it or for whether it serves any particular purpose or
  7. works at all, unless he says so in writing.  Refer to the GNU General Public
  8. License for full details.
  9.  
  10. Everyone is granted permission to copy, modify and redistribute libtek, but
  11. only under the conditions described in the GNU General Public License.  A copy
  12. of this license is supposed to have been given to you along with libtek so
  13. you can know your rights and responsibilities.  It should be in a file named
  14. COPYING.  Among other things, the copyright notice and this notice must be
  15. preserved on all copies.  */
  16.  
  17. /* This file is the arc routine, which is a standard part of the plot
  18.    library.  It draws an arc with the center at xc,yc, the beginning at
  19.    x0,y0 and the ending at x1,y1 */
  20.  
  21. #include "sys-defines.h"
  22. #include "libplot.h"
  23.  
  24. #ifdef NEED_DREM
  25. /* return the remainder of x/y */
  26. double drem (x, y)
  27.      double x, y;
  28. {
  29.   while (x>y/2.)
  30.     x -= y;
  31.   while (x<-y/2.)
  32.     x += y;
  33.   return x;
  34. }
  35. #endif
  36.  
  37. int
  38. arc (xc, yc, x0, y0, x1, y1)
  39.      int xc, yc, x0, y0, x1, y1;
  40. {
  41.   /* center: xc,yc
  42.      from: x0,y0
  43.      to: x1,y1 */
  44.   double dtheta, theta, theta_0, theta_1, x, y, radius;
  45.  
  46.   x = x0 - xc;            /* starting coordinate relatve to center */
  47.   y = y0 - yc;            /* of the circle. */
  48.   radius = sqrt (x*x + y*y);
  49.  
  50.   if (x != 0)            /* find the starting angle */
  51.     {
  52.       theta_0 = atan2 (y, x);
  53.     }
  54.   else
  55.     {
  56.       if (y>0)
  57.     theta_0 = M_PI/2.;
  58.       else
  59.     theta_0 = M_PI/-2.;
  60.     }
  61.       
  62.   x = x1 - xc;            /* ending coordinate relatve to center */
  63.   y = y1 - yc;            /* of the circle. */
  64.  
  65.   if (x != 0)            /* find the ending angle */
  66.     {
  67.       theta_1 = atan2 (y, x);
  68.     }
  69.   else
  70.     {
  71.       if (y>0)
  72.     theta_1 = M_PI/2.;
  73.       else
  74.     theta_1 = M_PI/-2.;
  75.     }
  76.   if (theta_1 <= theta_0)
  77.     theta_1 += 2. * M_PI;
  78.  
  79. #ifdef HAVE_ARC_OP
  80.   theta_0 *= 180. / M_PI;
  81.   theta_1 *= 180. / M_PI;
  82.  
  83.   fprintf (stdout, "\033/%d;%d;%d;%d;%dA", 
  84.        xc, yc, (int) radius, (int) theta_0,
  85.        (int) (theta_1 - theta_0));
  86.  
  87. #else /* HAVE_ARC_OP */
  88.   move (x0, y0);
  89.  
  90.   /*  we make dtheta proportional to the lenth of the arc so that
  91.       small arcs will look smooth. */
  92.   dtheta = (theta_1 - theta_0) /64.;
  93.  
  94.   for (theta = theta_0 + dtheta; theta < theta_1; theta += dtheta)
  95.     {
  96.       double xx, yy, xinc, yinc, distance_a, distance_b;
  97.       xx = radius*cos(theta);
  98.       yy = radius*sin(theta);
  99.  
  100.       /* choose the nearest pixel. */
  101.       if ( drem (theta, M_PI/2.) < M_PI/-4.)
  102.     {
  103.       xinc = 1.;
  104.       yinc = 0.;
  105.     }
  106.       else
  107.     {
  108.       xinc = 0.;
  109.       yinc = 1.;
  110.     }
  111.       distance_a = (int)(xx) * (int)(xx)
  112.     + (int)(yy) * (int)(yy) - radius * radius;
  113.       distance_b = (int)(xx+xinc) * (int)(xx+xinc)
  114.     + (int)(yy+yinc) * (int)(yy+yinc) - radius * radius;
  115.       if (distance_b < distance_a)
  116.     {
  117.       xx += xinc;
  118.       yy += yinc;
  119.     }
  120.       else
  121.     {
  122.       distance_b = (int)(xx-xinc) * (int)(xx-xinc)
  123.         + (int)(yy-yinc) * (int)(yy-yinc) - radius * radius;
  124.       if (distance_b < distance_a)
  125.         {
  126.           xx -= xinc;
  127.           yy -= yinc;
  128.         }
  129.     }
  130.       cont ((int) (xc + xx), (int) (yc + yy));
  131.     }
  132.   cont (x1, y1);
  133.   move (xc, yc);
  134. #endif /* HAVE_ARC_OP */
  135.   return 0;
  136. }
  137.